package query

import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.serializer.SerializerFeature
import com.trjcn.wxpay.model.request.{WXOrderQueryRequest, WXRefundQueryRequest}
import dto.req.QueryOrderReqDTO
import dto.resp.QueryOrderRespDTO
import enums.{PayChannelEnum, PayEnum, ThirdSystemErrorEnum}
import factory.ActionFactory
import org.springframework.beans.factory.InitializingBean
import org.springframework.stereotype.Service

@Service
class WXPayQueryAction extends BaseQueryAction with InitializingBean{

  override def getPayChannel: Integer = PayChannelEnum.WX_PAY.getId

  override def query[T <: QueryOrderReqDTO, R <: QueryOrderRespDTO](req: T, resp: R): R = {
    val queryRequest = new WXOrderQueryRequest
    queryRequest.setOutTradeNo(req.getPayOrderNo)
    log.info("wxpay query request params : {}", JSON.toJSONString(queryRequest, SerializerFeature.PrettyFormat))
    val queryResponse = wxPayService.query(queryRequest)
    log.info("wxpay query response result : {}", JSON.toJSONString(queryResponse, SerializerFeature.PrettyFormat))
    //BeanUtils.copyProperties(req, resp);
    if (!(queryResponse.getResultCode == wxPayProperties.WX_PAY_SUCCESS)) {
      resp.setOrderStatusCode(PayEnum.PayTradeStatusEnum.UN_KNOW.getCode)
      resp.setOrderStatusMessage(PayEnum.PayTradeStatusEnum.UN_KNOW.getDesc)
      resp.setThirdOrderStatusCode(ThirdSystemErrorEnum.getErrorEnum(queryResponse.getErrCode).getCode)
      resp.setThirdOrderStatusMessage(ThirdSystemErrorEnum.getErrorEnum(queryResponse.getErrCode).getMessage)
    } else {
      resp.setThirdOrderNo(queryResponse.getTransactionId)
      resp.setThirdOrderStatusCode(PayEnum.PayTradeStatusEnum.getByThirdCode(queryResponse.getTradeState.toUpperCase, req.getPayChannel).getThirdCode)
      resp.setThirdOrderStatusMessage(PayEnum.PayTradeStatusEnum.getByThirdCode(queryResponse.getTradeState.toUpperCase, req.getPayChannel).getDesc)
      resp.setOrderStatusCode(PayEnum.PayTradeStatusEnum.getByThirdCode(queryResponse.getTradeState.toUpperCase, req.getPayChannel).getCode)
      resp.setOrderStatusMessage(PayEnum.PayTradeStatusEnum.getByThirdCode(queryResponse.getTradeState.toUpperCase, req.getPayChannel).getDesc)
      resp.setRespBody(JSON.toJSONString(queryResponse, SerializerFeature.PrettyFormat))
    }
    resp
  }

  override def refundQuery[T <: QueryOrderReqDTO, R <: QueryOrderRespDTO](req: T, resp: R): R = {
    val refundQueryRequest = new WXRefundQueryRequest
    refundQueryRequest.setOutRefundNo(req.getPayOrderNo)
    log.info("wxpay refund query request params : {}", JSON.toJSONString(refundQueryRequest, SerializerFeature.PrettyFormat))
    val refundQueryResponse = wxPayService.refundQuery(refundQueryRequest)
    log.info("wxpay refund query response result : {} ", JSON.toJSONString(refundQueryResponse, SerializerFeature.PrettyFormat))
    if (!(refundQueryResponse.getResultCode == wxPayProperties.WX_PAY_SUCCESS)) {
      resp.setOrderStatusCode(PayEnum.PayTradeStatusEnum.UN_KNOW.getCode)
      resp.setOrderStatusMessage(PayEnum.PayTradeStatusEnum.UN_KNOW.getDesc)
      resp.setThirdOrderStatusCode(ThirdSystemErrorEnum.getErrorEnum(refundQueryResponse.getErrCode).getCode)
      resp.setThirdOrderStatusMessage(ThirdSystemErrorEnum.getErrorEnum(refundQueryResponse.getErrCode).getMessage)
    } else {
      resp.setThirdOrderNo(refundQueryResponse.getThirdOrderNo)
      resp.setThirdOrderStatusCode(PayEnum.RefundTradeStatusEnum.getByThirdCode(refundQueryResponse.getResultCode.toUpperCase, req.getPayChannel).getThirdCode)
      resp.setThirdOrderStatusMessage(PayEnum.RefundTradeStatusEnum.getByThirdCode(refundQueryResponse.getResultCode.toUpperCase, req.getPayChannel).getDesc)
      resp.setOrderStatusCode(PayEnum.RefundTradeStatusEnum.getByThirdCode(refundQueryResponse.getResultCode.toUpperCase, req.getPayChannel).getCode)
      resp.setOrderStatusMessage(PayEnum.RefundTradeStatusEnum.getByThirdCode(refundQueryResponse.getResultCode.toUpperCase, req.getPayChannel).getDesc)
      resp.setRespBody(JSON.toJSONString(refundQueryResponse, SerializerFeature.PrettyFormat))
    }
    resp
  }

  override def afterPropertiesSet(): Unit = ActionFactory.setQueryAction(getPayChannel, this)
}
